<?php
namespace App\Libs\Common;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class FaceController extends Controller
{

    public $sign='';
    public $responseAarray='';

    public function _initialize()
    {
        header('Content-type:text/html;charset=utf-8');   //声明头文件

        $API_KEY="XGAyOSIIvat8GGMQvFmrtpZ_bSqwHFZq";
        $API_SECRET="8U4UPHryRg1P0_PAHa4DvvkCPgoU6Hpl";

        $this->sign=$this->gen_sign($API_KEY,$API_SECRET,10);

        define('GETTOKEN','https://openapi.faceid.com/lite/v1/get_biz_token');  //请求token路径
        define('JUDGEHTML',' https://openapi.faceid.com/lite/v1/do/');//转跳到对应的网页验证路径
        define('GETRESULT','https://openapi.faceid.com/lite/v1/get_result');//返回结果

        //可改路径  返回路径并且执行getResult方返回数据 //测试  本地路径
        //define('RETURNURL','http://192.168.31.159/lvyue/OutApi/Face/judgeIdcard');//用户完成或取消验证后网页跳转的目标URL。
        //define('NOTIFYURL',"http://192.168.31.159/lvyue/OutApi/Face/judgeIdcard");//用户完成验证、取消验证、或验证超时后，由FaceID服务器请求客户服务器的URL
   
         //服务器路径
        define('RETURNURL','http://pic.lvyuecp.com/OutApi/Face/judgeIdcard');//用户完成或取消验证后网页跳转的目标URL。
        define('NOTIFYURL',"http://pic.lvyuecp.com/OutApi/Face/judgeIdcard");//用户完成验证、取消验证、或验证超时后，由FaceID服务器请求客户服务器的URL
 
    }


    /**
     * 执行验证身份证开始
     * $phone   手机号  11位 string   POST提交
     * $token   身份标识
     * $order_id   身份标识
     */
    public function judgeStart()
    {
        $phone = I('phone','');
        $token = I('token',''); 
        $order_id = I('order_id',''); 

        checkToken($phone,$token);

        /**整合传输数据**/
        $curlInfo = [
            'sign' => $this->sign,
            'sign_version' =>'hmac_sha1',
            'return_url' => RETURNURL,
            'notify_url' => NOTIFYURL,          
            'biz_no' => $phone.rand(1000,999999),  //用来生成唯一的值
            'group' => "1",
            'liveness_type' => "video_number",
            'comparison_type' => 1, //设定本次核身服务的类型 有源比对”（“1”）或“无源比对”（“0”）
            'idcard_mode' => 2,    //有源比对时（comparison_type ＝ '(0,1,2,3)'） 2表示上传身份证正反面
            'web_title' => '刷脸认证', //用来替换tabBar上的内容
        ];
		
        $response = $this->requestCurl(GETTOKEN,'POST',$curlInfo); //获取token值
		
        if ($response['biz_token']) 
        {
            $res=M('user_face_biz_token')->add(['phone'=>$phone,'token'=>$token,'order_id'=>$order_id,'biz_token'=>$response['biz_token'],'create_time'=>time()]);

            if ($res) 
            {
                header('location:'.JUDGEHTML.$response['biz_token']); //跳转到验证的网页
            } 
        }

        return;
    }

    /**
     * @请求getResult方法返回数据
     * 此方法的调用是根据  常量 RETURNURL   NOTIFYURL (即当前控制器路径)
     * 当用户提交信息或放弃验证时将数据返回到该方法
     * 功能: 进行数据判断,是否通过身份认证
     */
    public function judgeIdcard()
    {

        $biz_token=I('biz_token','');

        $curlInfo = [
            'sign' => $this->sign,
            'sign_version' =>'hmac_sha1',
            'biz_token' => $biz_token
        ];

        
        $response = $this->requestCurl(GETRESULT,'GET',$curlInfo); //返回信息

        $response=$this->returnRowArray($response);  //被处理后的一维数组

        //插入数据
        $this->gement($response);//被处理过得要添加(或更新)的信数据

        $row=M('user_face_biz_token')->where("biz_token='$biz_token'")->find();

        if ($response['result_code'] != '1000') 
        {
            //未通过跳转地址
            $url="https://n.lvyuecp.com/waphb/faceAuth/faceResult.html?phone=$row[phone]&token=$row[token]&order_id=$row[order_id]&result=fail";
        }else{
            //成功跳转地址
            $url="https://n.lvyuecp.com/waphb/faceAuth/faceResult.html?phone=$row[phone]&token=$row[token]&order_id=$row[order_id]&result=success";
        }

        header("location:$url");

        return;
    }


    /**
     * 多维数组转一维数组
     * @param  [array] 多维数组 
     * @return array   一维数组
     */
    private function returnRowArray($res)
    {
        foreach ($res as $key => $value) 
        {
           if (is_array($value) && count($value) > 0)   
           {
                $this->returnRowArray($value,$this->responseAarray);
                
           }else{

                if ($value) 
                {
                    $this->responseAarray[$key]=$value;
                }
           } 
        }

        return $this->responseAarray; 
    }
	

    /**
     * @param $info  数组(经过arrGem方法处理后返回的数组信息)
     * @return mixed
     * 返回要插入或更新的数据表的数组信息
     */
    private function gement($array)
    {
        //判断名字
        if(array_key_exists('name',$array)) 
        {
            $add['name'] = $array['name'];

        }else{

            return false;
        }

        //判断身份证号码
        if(array_key_exists('idcard_number',$array))
        {
            $add['idCard'] = $array['idcard_number'];
        }

        //判断有效期
        if(array_key_exists('valid_date_start',$array) || array_key_exists('valid_date_end',$array))
        {
            $add['idcard_valid_time'] =$array['valid_date_start'].'-'.$array['valid_date_end'];
        }

        //年月日
        if(array_key_exists('birth_year',$array))
        {
            $add['idcard_year'] =$array['birth_year'];
        }

        if(array_key_exists('birth_month',$array))
        {
            $add['idcard_month'] =$array['birth_month'];
        }

        if(array_key_exists('birth_day',$array))
        {
            $add['idcard_day'] =$array['birth_day'];
        }

        //民族
        if(array_key_exists('nationality',$array))
        {
            $add['idcard_race'] = $array['nationality'];
        }

        //住址
        if(array_key_exists('address',$array))
        {
            $add['idcard_address'] =$array['address'];
        }

        //性别
        if(array_key_exists('gender',$array))
        {
            $add['idcard_gender'] =$array['gender'];
        }

         //身份证正面照片
        if(array_key_exists('idcard_frontside',$array))
        {
            $add['id_number_front'] = $this->bases64($array['idcard_frontside'],$add['idCard']);
        }


         //身份证反面照片
        if(array_key_exists('idcard_backside',$array))
        {
            $add['id_number_behind'] = $this->bases64($array['idcard_backside'],$add['idCard']);
        }

       
        /*  
        if(array_key_exists('idcard_portrait',$array))
        {
            $add['face_photo'] = $this->bases64($array['idcard_portrait'],$add['idCard']);
        }*/

         //活体检测抓取照片
        if(array_key_exists('image_best',$array))
        {
            $add['face_photo'] = $this->bases64($array['image_best'],$add['idCard']);
        }

        $add['face_state'] = $array['result_code'] == '1000'?2:1; //判断状态

        $add['biz_token'] = $array['biz_token']; 

        $phone = substr($array['biz_no'],0,11); //获取手机号

        $isCount = M('user_face_risk')->where(['phone'=>$phone])->count();//根据手机号判断是否已储存

        if(!$isCount)
        {
            $add['phone'] = $phone;
            
            $res=M('user_face_risk')->add($add);

        }else{

            $res=M('user_face_risk')->where("phone=$phone")->save($add);
        }

        if ($res) return true;

        return false;
    }


    /**
     * @param $baseImage  base64编码
     * @return array  返回解密后的文件路径
     */
    private  function bases64($baseImage,$fileName)
    {
         $imagePath = [];

         $filePath = 'Uploads/faceID/'.$fileName.'/';  //定义保存路径
         
         $new_file = $filePath.md5(rand(1000,999999)).'.png';

        if (is_string($baseImage)) 
        {
           if(preg_match('/^(data:\s*image\/(\w+);base64,)/', $baseImage,$result))
            { 
                //正则匹配
                $fileName = $key.time().'.'.$result[2];

                if(!file_exists($filePath))
                {
                    //检查是否有该文件夹，如果没有就创建，并给予最高权限
                    mkdir($filePath, 0700);
                }

                $savepath = $filePath . $fileName; //文件路径

                if(file_put_contents($savepath, base64_decode(str_replace($result[1], '', $baseImage))))
                {
                    array_push($imagePath, $savepath);
                } //将整个文件读入一个字符串

                return $imagePath;   //返回图片路径

            }else{

                if(!file_exists($filePath))
                {
                    //检查是否有该文件夹，如果没有就创建，并给予最高权限
                    mkdir($filePath, 0700);
                }

               $res=file_put_contents($new_file, base64_decode($baseImage));

               if ($res) 
               {
                   return $new_file;
               }
               
            }
        }
    
        return false;
    }


    /**
     *  CURL 请求
     * @param $url        string     请求路径
     * @param $type       string     请求方式
     * @param $curlInfo   array      请求信息
     * @return mixed     返回信息
     */
    private function requestCurl($url,$type,$curlInfo)
    {
        $ch = curl_init();  //初始化请求

        $opention = [
            CURLOPT_URL            => $url,     //请求路径
            CURLOPT_CUSTOMREQUEST  => $type,        //启用post提交
            CURLOPT_SSL_VERIFYPEER => false,       //禁止验证SSL证书
            CURLOPT_RETURNTRANSFER => true,        //获取的信息作为变量储存，不直接输出
            CURLOPT_ENCODING       => "",          //如果为空字符串""，会发送所有支持的编码类型
            CURLOPT_FOLLOWLOCATION => true,        //TRUE 时将会根据服务器返回 HTTP 头中的 "Location: " 重定向
            CURLOPT_TIMEOUT        => 30,           //设置cURL允许执行的最长秒数。
            CURLOPT_POSTFIELDS     => $curlInfo    //传输参数
        ];

        curl_setopt_array($ch,$opention);  //设置的curl的属性

        $response = curl_exec($ch);    //执行请求并返回数据

        curl_close ($ch);     //关闭请求

        $response = json_decode($response,true);

        return $response;
    }

    /** 
     *  生成签名
     */
    private function gen_sign($apiKey, $apiSecret, $expired)
    {
        $rdm = rand();
        $current_time = time();
        $expired_time = $current_time + $expired;
        $srcStr = "a=%s&b=%d&c=%d&d=%d";
        $srcStr = sprintf($srcStr, $apiKey, $expired_time, $current_time, $rdm);
        $sign = base64_encode(hash_hmac('SHA1', $srcStr, $apiSecret, true).$srcStr);
        return $sign;
    }



}